/* getline.c -- Replacement for GNU C library function getline

Copyright (C) 1993 Free Software Foundation, Inc.

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.

This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
General Public License for more details.  */

/* Written by Jan Brittenson, bson@gnu.ai.mit.edu.  */
#if 0
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include <sys/types.h>
#include <stdio.h>
#include <assert.h>
#include <errno.h>

#if STDC_HEADERS
#include <stdlib.h>
#else
char *malloc (), *realloc ();
#endif

/* Always add at least this many bytes when extending the buffer.  */
#define MIN_CHUNK 64

/* Read up to (and including) a TERMINATOR from STREAM into *LINEPTR
   + OFFSET (and null-terminate it). *LINEPTR is a pointer returned from
   malloc (or NULL), pointing to *N characters of space.  It is realloc'd
   as necessary.  Return the number of characters read (not including the
   null terminator), or -1 on error or EOF.  On a -1 return, the caller
   should check feof(), if not then errno has been set to indicate
   the error.  */

int
getstr (lineptr, n, stream, terminator, offset)
     char **lineptr;
     size_t *n;
     FILE *stream;
     char terminator;
     int offset;
{
  int nchars_avail;		/* Allocated but unused chars in *LINEPTR.  */
  char *read_pos;		/* Where we're reading into *LINEPTR. */
  int ret;

  if (!lineptr || !n || !stream)
    {
      errno = EINVAL;
      return -1;
    }

  if (!*lineptr)
    {
      *n = MIN_CHUNK;
      *lineptr = malloc (*n);
      if (!*lineptr)
	{
	  errno = ENOMEM;
	  return -1;
	}
    }

  nchars_avail = *n - offset;
  read_pos = *lineptr + offset;

  for (;;)
    {
      int save_errno;
      register int c = getc (stream);

      save_errno = errno;

      /* We always want at least one char left in the buffer, since we
	 always (unless we get an error while reading the first char)
	 NUL-terminate the line buffer.  */

      assert((*lineptr + *n) == (read_pos + nchars_avail));
      if (nchars_avail < 2)
	{
	  if (*n > MIN_CHUNK)
	    *n *= 2;
	  else
	    *n += MIN_CHUNK;

	  nchars_avail = *n + *lineptr - read_pos;
	  *lineptr = realloc (*lineptr, *n);
	  if (!*lineptr)
	    {
	      errno = ENOMEM;
	      return -1;
	    }
	  read_pos = *n - nchars_avail + *lineptr;
	  assert((*lineptr + *n) == (read_pos + nchars_avail));
	}

      if (ferror (stream))
	{
	  /* Might like to return partial line, but there is no
	     place for us to store errno.  And we don't want to just
	     lose errno.  */
	  errno = save_errno;
	  return -1;
	}

      if (c == EOF)
	{
	  /* Return partial line, if any.  */
	  if (read_pos == *lineptr)
	    return -1;
	  else
	    break;
	}

      *read_pos++ = c;
      nchars_avail--;

      if (c == terminator)
	/* Return the line.  */
	break;
    }

  /* Done - NUL terminate and return the number of chars read.  */
  *read_pos = '\0';

  ret = read_pos - (*lineptr + offset);
  return ret;
}

int
_getline (lineptr, n, stream)
     char **lineptr;
     size_t *n;
     FILE *stream;
{
  return getstr (lineptr, n, stream, '\n', 0);
}

#endif

#include<stdio.h>
#include<string.h>/*supply the strlen() */
#include<malloc.h>
#include<stdlib.h>

#define TRUE    1
#define FALSE   0
#define OK      1
#define ERROR   0
#define INFEASIBLE  -1
#define OVERFLOW    -2
typedef int Status;

//这里主要用到了单个的"#"。单个的"#"出现在宏中，表示对#后面的变量替换后，用双引号引起来
#define __PN(name)  printf("%s\n", #name)

//主要打印指针地址用
#define __PV(name)  printf("0x%X\n", name)
#define __PNV(name) printf("The value of %s is %d\n",#name,name)
#define __PL printf("%s : I'm in line %d\n",__FILE__,__LINE__)
#define __PC(name) printf("The char is %c\n",name)
#define _tolower(X) ((X)|((char) 0x20))
void __PA(char * array,int length,char * format)
{
	int i=0;
	int isnum=0;
	int hexflag=0;
	int row=1;
	if(0 != strcmp(format,"%c"))
	{
        isnum=1;
	}
	if(0 == strcmp(format,"%x") || 0 == strcmp(format,"%X"))
	{
        hexflag=1;
	}
	for (i=0;i<length;i++)
	{
		if(hexflag==1)
		{
		    printf("0x");
		}
		printf(format,array[i]);
		if(isnum==1)
        {
            printf(" ");
            if(row == 16)
            {
                printf("\n");
                row=1;
            }
            else
            {
                row++;
            }
        }
        else
        {
            if(row == 50)
            {
                printf("\n");
                row=1;
            }
            else
            {
                row++;
            }
        }
    }
	printf("\n");
}

static char bb_process_escape_sequence(const char **ptr)
{
	static const char charmap[] = {
		'a',  'b',  'f',  'n',  'r',  't',  'v',  '\\', 0,
		'\a', '\b', '\f', '\n', '\r', '\t', '\v', '\\', '\\' };

	const char *p;
	const char *q;
	unsigned int num_digits;
	unsigned int r;
	unsigned int n;
	unsigned int d;
	unsigned int base;

	num_digits = n = 0;
	base = 8;
	q = *ptr;

#ifdef WANT_HEX_ESCAPES
	if (*q == 'x') {
		++q;
		base = 16;
		++num_digits;
	}
#endif

	do {
		d = (unsigned int)(*q - '0');
#ifdef WANT_HEX_ESCAPES
		if (d >= 10) {
			d = ((unsigned int)(_tolower(*q) - 'a')) + 10;
		}
#endif

		if (d >= base) {
#ifdef WANT_HEX_ESCAPES
			if ((base == 16) && (!--num_digits)) {
/* 				return '\\'; */
				--q;
			}
#endif
			break;
		}

		r = n * base + d;
		if (r > 255) {
			break;
		}

		n = r;
		++q;
	} while (++num_digits < 3);

	if (num_digits == 0) {	/* mnemonic escape sequence? */
		p = charmap;
		do {
			if (*p == *q) {
				q++;
				break;
			}
		} while (*++p);
		n = *(p+(sizeof(charmap)/2));
		__PV(n);
	}

	*ptr = q;

	return (char) n;
}
Status main(int argc, char *argv[])
{
    char x[8];
    x[0]='\\';
    x[1]='0';
    x[2]='3';
    x[3]='2';
    x[4]='a';
    x[5]='b';
    x[6]='c';

    const char *prmt_ptr=x;
    char  c;

    c = *prmt_ptr++;

		if (c == '\\') {
			const char *cp = prmt_ptr;

			c = bb_process_escape_sequence(&prmt_ptr);
			__PC(c);
			if(prmt_ptr==cp) {
			  if (*cp == 0)
				return -1;
			  c = *prmt_ptr++;
			  __PC(c);
			}
		}
}

#if 0
int main()
{
	FILE * fp;
	char * line = NULL;
	size_t len = 0;
	ssize_t read;
	fp = fopen("aijs.txt", "r");
	if (fp == NULL)
		return -1;
	while ((read = _getline(&line, &len, fp)) != -1)
	{
		printf("Retrieved line of length %d :\n", read);
		printf("%s", line);
	}
	if (line)
		printf("%s\n",line);
    return 0;
}
#endif
